package cn.anecansaitin.whimsy.test.explayer;

import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
import software.bernie.geckolib.constant.DataTickets;
import software.bernie.geckolib.core.animatable.model.CoreGeoBone;
import software.bernie.geckolib.core.animation.AnimationState;
import software.bernie.geckolib.core.molang.MolangParser;
import software.bernie.geckolib.core.molang.MolangQueries;
import software.bernie.geckolib.model.DefaultedGeoModel;
import software.bernie.geckolib.model.data.EntityModelData;
import software.bernie.geckolib.util.RenderUtils;

public class GeoPlayerModel extends DefaultedGeoModel<GeoPlayer> {
    private boolean turnsHead = true;

    public GeoPlayerModel(ResourceLocation modelPath, ResourceLocation animationPath) {
        super(modelPath);
        withAltAnimations(animationPath);
    }

    @Override
    public ResourceLocation getTextureResource(GeoPlayer animatable) {
        return animatable.getCurrentPlayer().getSkin().texture();
    }

    @Override
    public void setCustomAnimations(GeoPlayer geoPlayer, long instanceId, AnimationState<GeoPlayer> animationState) {
//        if (!this.turnsHead) {
//            return;
//        }
//
//        CoreGeoBone head = getAnimationProcessor().getBone("Head");
//
//        if (head != null ) {
//            EntityModelData entityData = animationState.getData(DataTickets.ENTITY_MODEL_DATA);
//
//            head.setRotX(head.getRotX() + entityData.headPitch() * Mth.DEG_TO_RAD);
//            head.setRotY(head.getRotY() + entityData.netHeadYaw() * Mth.DEG_TO_RAD);
//        }
    }

    @Override
    protected String subtype() {
        return "player";
    }

    @Override
    public void applyMolangQueries(GeoPlayer animatable, double animTime) {
        MolangParser parser = MolangParser.INSTANCE;
        Minecraft mc = Minecraft.getInstance();
        LocalPlayer currentPlayer = animatable.getCurrentPlayer();

        parser.setMemoizedValue(MolangQueries.LIFE_TIME, () -> animTime / 20d);
        parser.setMemoizedValue(MolangQueries.ACTOR_COUNT, mc.level::getEntityCount);
        parser.setMemoizedValue(MolangQueries.TIME_OF_DAY, () -> mc.level.getDayTime() / 24000f);
        parser.setMemoizedValue(MolangQueries.MOON_PHASE, mc.level::getMoonPhase);

        parser.setMemoizedValue(MolangQueries.DISTANCE_FROM_CAMERA, () -> mc.gameRenderer.getMainCamera().getPosition().distanceTo(currentPlayer.position()));
        parser.setMemoizedValue(MolangQueries.IS_ON_GROUND, () -> RenderUtils.booleanToFloat(currentPlayer.onGround()));
        parser.setMemoizedValue(MolangQueries.IS_IN_WATER, () -> RenderUtils.booleanToFloat(currentPlayer.isInWater()));
        parser.setMemoizedValue(MolangQueries.IS_IN_WATER_OR_RAIN, () -> RenderUtils.booleanToFloat(currentPlayer.isInWaterRainOrBubble()));

        parser.setMemoizedValue(MolangQueries.HEALTH, currentPlayer::getHealth);
        parser.setMemoizedValue(MolangQueries.MAX_HEALTH, currentPlayer::getMaxHealth);
        parser.setMemoizedValue(MolangQueries.IS_ON_FIRE, () -> RenderUtils.booleanToFloat(currentPlayer.isOnFire()));
        parser.setMemoizedValue(MolangQueries.GROUND_SPEED, () -> {
            Vec3 velocity = currentPlayer.getDeltaMovement();

            return Mth.sqrt((float) ((velocity.x * velocity.x) + (velocity.z * velocity.z)));
        });
        parser.setMemoizedValue(MolangQueries.YAW_SPEED, () -> currentPlayer.getViewYRot((float) animTime - currentPlayer.getViewYRot((float) animTime - 0.1f)));
    }
}
